home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume9 / teco / part02 < prev    next >
Encoding:
Internet Message Format  |  1987-03-11  |  52.2 KB

  1. Subject:  v09i029:  A TECO text editor, Part02/04
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: genrad!mlf
  6. Mod.sources: Volume 9, Issue 29
  7. Archive-name: teco/Part02
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 2 (of 4)."
  14. # Contents:  te_chario.c te_defs.h te_srch.c te_subs.c
  15. # Wrapped by rs@mirror on Thu Mar 12 19:54:28 1987
  16. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  17. echo shar: Extracting \"te_chario.c\" \(9049 characters\)
  18. if test -f te_chario.c ; then 
  19.   echo shar: Will not over-write existing file \"te_chario.c\"
  20. else
  21. sed "s/^X//" >te_chario.c <<'END_OF_te_chario.c'
  22. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  23. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  24. X/* They may be copied if this copyright notice is included                    */
  25. X
  26. X/* te_chario.c   character I/O routines   10/9/86 */
  27. X#include <errno.h>
  28. X#include "te_defs.h"
  29. X
  30. X#include <fcntl.h>
  31. X#ifndef DEBUG
  32. X#include <signal.h>
  33. Xextern int int_handler();
  34. Xextern int stp_handler();
  35. Xextern int hup_handler();
  36. X#define SIGINTMASK 2
  37. X#endif
  38. X
  39. Xint lf_sw;                                    /* nonzero: make up a LF following an entered CR */
  40. Xint ttyflags;                                /* flags for (stdin) file descriptor */
  41. Xstruct tchars tc_orig, tc_new, tc_noint;    /* original, new, disabled intrpt tty special chars */
  42. Xstruct ltchars lc_orig, lc_new;                /* original and new local special chars */
  43. Xstruct sgttyb tty_orig, tty_new;            /* original and new tty flags */
  44. Xint tty_local;                                /* original tty local mode flags */
  45. Xint lnoflsh = LNOFLSH;                        /* bit to force "no flush on interrupt */
  46. X
  47. X#ifndef DEBUG
  48. Xstruct sigvec intsigstruc = { int_handler, 0, 0 } ;        /* info structure for ^C interrupt        */
  49. Xstruct sigvec stpsigstruc = { stp_handler, 0, 0 } ;        /* info structure for "stop" signal        */
  50. Xstruct sigvec hupsigstruc = { hup_handler, 0, 0 } ;        /* info structure for "hangup" signal    */
  51. Xstruct sigvec nosigstr = { SIG_DFL, 0, 0 };                /* default structure for signal            */
  52. X#endif
  53. X
  54. Xint inp_noterm;                /* nonzero if standard input is not a terminal */
  55. Xint out_noterm;                /* nonzero if standard output is not a terminal */
  56. X /* set tty (stdin) mode.  TECO mode is CBREAK, no ECHO, sep CR & LF                */
  57. X/* operation; normal mode is none of the above.  TTY_OFF and TTY_ON do this        */
  58. X/* absolutely; TTY_SUSP and TTY_RESUME use saved signal status.                    */
  59. X
  60. Xsetup_tty(arg)
  61. X    int arg;
  62. X    {
  63. X    extern int errno;
  64. X    int ioerr;
  65. X    struct sgttyb tmpbuf;
  66. X
  67. X/* initial processing: set tty mode */
  68. X
  69. X    if (arg == TTY_ON)
  70. X        {
  71. X        ioerr = ioctl(fileno(stdin), TIOCGETP, &tty_orig);    /* get std input characteristics */
  72. X        inp_noterm = (ioerr && (errno == ENOTTY));            /* nonzero if input not a terminal */
  73. X        ioerr = ioctl(fileno(stdout), TIOCGETP, &tmpbuf);    /* get std output characteristics */
  74. X        out_noterm = (ioerr && (errno == ENOTTY));            /* nonzero if output not a terminal */
  75. X        ioctl(fileno(stdout), TIOCLGET, &tty_local);        /* get current "local mode flags" word */
  76. X
  77. X        ttybuf = tty_new = tty_orig;                        /* make a copy of tty control structure */
  78. X        tty_new.sg_flags = (tty_new.sg_flags & ~ECHO & ~CRMOD) | CBREAK;    /* turn on teco modes */
  79. X
  80. X        ioctl(fileno(stdin), TIOCGETC, &tc_orig);        /* read current tchars */
  81. X        tc_new = tc_orig;                                /* make local copy */
  82. X        tc_new.t_quitc = tc_new.t_brkc = -1;            /* disable "quit" and "delimiter" chars */
  83. X        tc_noint = tc_new;
  84. X        tc_noint.t_intrc = -1;                            /* disable the interrupt char in this one */
  85. X
  86. X        ioctl(fileno(stdin), TIOCGLTC, &lc_orig);        /* read current ltchars */
  87. X        lc_new = lc_orig;                                /* make local copy */
  88. X        lc_new.t_rprntc = lc_new.t_werasc = lc_new.t_lnextc = -1;    /* disable "reprint," "word erase," "lit next" */
  89. X        }
  90. X
  91. X    if ((arg == TTY_ON) || (arg == TTY_RESUME))
  92. X        {
  93. X        ioctl(fileno(stdin), TIOCSETP, &tty_new);        /* set flags for teco */
  94. X        ioctl(fileno(stdin), TIOCSETC, &tc_new);        /* update both */
  95. X        ioctl(fileno(stdin), TIOCSLTC, &lc_new);
  96. X        ioctl(fileno(stdout), TIOCLBIS, &lnoflsh);        /* disable "interrupt => flush buffers" */
  97. X#ifndef DEBUG
  98. X        sigvec(SIGTSTP, &stpsigstruc, 0);                /* set up to trap "stop" signal */
  99. X        sigvec(SIGINT, &intsigstruc, 0);                /* and "interrupt" signal */
  100. X        sigvec(SIGHUP, &hupsigstruc, 0);                /* and "hangup" signal */
  101. X#endif
  102. X        }
  103. X    else
  104. X        {
  105. X        ioctl(fileno(stdin), TIOCSETP, &tty_orig);        /* set flags back to original */
  106. X        ioctl(fileno(stdin), TIOCSETC, &tc_orig);        /* put both back to orig states */
  107. X        ioctl(fileno(stdin), TIOCSLTC, &lc_orig);
  108. X        ioctl(fileno(stdout), TIOCLSET, &tty_local);    /* restore local mode flags to original states */
  109. X#ifndef DEBUG
  110. X        sigvec(SIGTSTP, &nosigstr, 0);                    /* restore default signal handling */
  111. X        sigvec(SIGINT, &nosigstr, 0);
  112. X        sigvec(SIGHUP, &nosigstr, 0);
  113. X#endif
  114. X        }
  115. X    }
  116. X /* routines to handle keyboard input */
  117. X
  118. X/* routine to get a character without waiting, used by ^T when ET & 64 is set    */
  119. X/* if lf_sw is nonzero, return the LF; else use the FNDELAY fcntl to inquire of the input */
  120. X
  121. Xint gettty_nowait()
  122. X    {
  123. X    int c;
  124. X
  125. X    if (lf_sw)
  126. X        {
  127. X        lf_sw = 0;
  128. X        return(LF);            /* LF to be sent: return it */
  129. X        }
  130. X    fcntl(fileno(stdin), F_SETFL, ttyflags | FNDELAY);        /* set to "no delay" mode */
  131. X    while (!(c = getchar()));                    /* read character, or -1, skip nulls */
  132. X    fcntl(fileno(stdin), F_SETFL, ttyflags);                /* reset to normal mode */
  133. X    if (c == CR) ++lf_sw;                        /* CR: set switch to make up a LF */
  134. X    return(c);
  135. X    }
  136. X
  137. X
  138. X
  139. X/* normal routine to get a character */
  140. X
  141. Xint in_read = 0;        /* flag for "read busy" (used by interrupt handler) */
  142. X
  143. Xchar gettty()
  144. X    {
  145. X    int c;
  146. X
  147. X    if (lf_sw)
  148. X        {
  149. X        lf_sw = 0;
  150. X        return(LF);        /* if switch set, make up a line feed */
  151. X        }
  152. X    ++in_read;                            /* set "read busy" switch */
  153. X    while(!(c = getchar()));                /* get character; skip nulls */
  154. X    in_read = 0;                        /* clear switch */
  155. X    if (c == CR) ++lf_sw;                    /* CR: set switch to make up a LF */
  156. X    if (c == EOF) ERROR(E_EFI);                /* end-of-file from standard input */
  157. X    return( (char) c & 0177);                /* and return the 7-bit char */
  158. X    }
  159. X
  160. X#ifndef DEBUG
  161. X
  162. X/* routine to handle interrupt signal */
  163. X
  164. Xint_handler()
  165. X    {
  166. X
  167. X    if (exitflag <= 0)                        /* if executing commands */
  168. X        {
  169. X        if (et_val & ET_CTRLC) et_val &= ~ET_CTRLC;        /* if "trap ^C" set, clear it and ignore */
  170. X        else exitflag = -2;                                /* else set flag to stop execution */
  171. X        }
  172. X    if (in_read)                            /* if interrupt happened in "getchar" pass a ^C to input */
  173. X        {
  174. X        in_read = 0;                                    /* clear "read" switch */
  175. X        ioctl(fileno(stdin), TIOCSETC, &tc_noint);        /* disable interrupt char */
  176. X        qio_char(CTL (C));                                /* send a ^C to input stream */
  177. X        ioctl(fileno(stdin), TIOCSETC, &tc_new);        /* reenable interrupt char */
  178. X        }
  179. X    }
  180. X#endif
  181. X /* routine to disable (1), enable (0) ^C interrupt, used to block interrupts during display update */
  182. X
  183. Xint old_mask;                /* storage for previous signal mask */
  184. X#define INT_MASK 2
  185. X
  186. Xblock_inter(func)
  187. X    int func;
  188. X    {
  189. X#ifndef DEBUG
  190. X    if (func) old_mask = sigblock(INT_MASK);            /* if arg nonzero, block interrupt */
  191. X    else sigsetmask(old_mask);                            /* otherwise restore old signal mask */
  192. X#endif
  193. X    }
  194. X
  195. X
  196. X
  197. X#ifndef DEBUG
  198. X/* routine to handle "stop" signal (^Y) */
  199. X
  200. Xstp_handler()
  201. X    {
  202. X    window(WIN_SUSP);                /* restore screen */
  203. X    setup_tty(TTY_SUSP);            /* put tty back to normal */
  204. X    sigvec(SIGTSTP, &nosigstr, 0);     /* put default action back */
  205. X    sigsetmask(0);                    /* unblock "suspend" signal */
  206. X    kill(0, SIGTSTP);                /* suspend this process */
  207. X
  208. X/* ----- process gets suspended here ----- */
  209. X
  210. X    sigvec(SIGTSTP, &stpsigstruc, 0);    /* restore local handling of "stop" signal */
  211. X    setup_tty(TTY_RESUME);                /* restore tty */
  212. X    buff_mod = 0;                        /* set whole screen modified */
  213. X    if (win_data[7])            /* redraw window */
  214. X        {
  215. X        window(WIN_RESUME);        /* re-enable window */
  216. X        window(WIN_REDRAW);        /* force complete redraw */
  217. X        window(WIN_REFR);        /* and refresh */
  218. X        }
  219. X    qio_char('\0');                /* wake up the input
  220. X    if (exitflag) retype_cmdstr('*');    /* if not executing, prompt again and echo command string so far */
  221. X    }
  222. X#endif
  223. X
  224. X
  225. X
  226. X/* simulate a character's having been typed on the keyboard */
  227. X
  228. Xqio_char(c)
  229. X    char c;
  230. X    {
  231. X    ioctl(fileno(stdin), TIOCSTI, &c);                /* send char to input stream */
  232. X    }
  233. X /* routine to handle "hangup" signal */
  234. X#ifndef DEBUG
  235. X
  236. Xhup_handler()
  237. X    {
  238. X    if (!exitflag) exitflag = -3;                    /* if executing, set flag to terminate */
  239. X    else
  240. X        {
  241. X        panic();                                    /* dump buffer and close output files */
  242. X        exit(1);
  243. X        }
  244. X    }
  245. X#endif
  246. X
  247. X
  248. X
  249. X/* type a crlf */
  250. X
  251. Xcrlf()
  252. X    {
  253. X    type_char(CR);
  254. X    type_char(LF);
  255. X    }
  256. X
  257. X
  258. X
  259. X/* reset ^O status */
  260. X
  261. Xint lflusho = LFLUSHO;
  262. Xint lfo;
  263. X
  264. Xreset_ctlo()
  265. X    {
  266. X    ioctl(fileno(stdin), TIOCLGET, &lfo);        /* read flags */
  267. X    if (lfo & LFLUSHO)                            /* if ^O was set */
  268. X        {
  269. X        ioctl(fileno(stdin), TIOCLBIC, &lflusho);    /* reset ^O */
  270. X        crlf();                                        /* type a crlf */
  271. X        }
  272. X    }
  273. X /* routine to type one character */
  274. X
  275. Xtype_char(c)
  276. X    char c;
  277. X    {
  278. X
  279. X    if ((char_count >= WN_width) && (c != CR) && !(spec_chars[c] & A_L))    /* spacing char beyond end of line */
  280. X        {
  281. X        if (et_val & ET_TRUNC) return;        /* truncate output to line width */
  282. X        else crlf();                        /* otherwise do automatic new line (note recursive call to type_char) */
  283. X        }
  284. X
  285. X    if ((c & 0140) == 0)                /* control char? */
  286. X        {
  287. X        switch (c & 0177)
  288. X            {
  289. X            case CR:
  290. X                putchar(c);
  291. X                char_count = 0;
  292. X                break;
  293. X
  294. X            case LF:
  295. X                putchar(c);
  296. X/*                scroll_dly();            /* filler chars in case VT-100 scrolls */
  297. X                break;
  298. X
  299. X            case ESC:
  300. X                if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
  301. X                else
  302. X                    {
  303. X                    putchar('$');
  304. X                    char_count++;
  305. X                    }
  306. X                break;
  307. X
  308. X            case TAB:
  309. X                if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
  310. X                else for (type_char(' '); (char_count & tabmask) != 0; type_char(' '));
  311. X                break;
  312. X
  313. X            default:
  314. X                if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
  315. X                else
  316. X                    {
  317. X                    putchar('^');
  318. X                    putchar(c + 'A'-1);
  319. X                    char_count += 2;
  320. X                    }
  321. X                break;
  322. X            }
  323. X        }
  324. X    else
  325. X        {
  326. X        putchar(c);
  327. X        char_count++;
  328. X        }
  329. X    }
  330. X
  331. END_OF_te_chario.c
  332. if test 9049 -ne `wc -c <te_chario.c`; then
  333.     echo shar: \"te_chario.c\" unpacked with wrong size!?
  334. fi
  335. # end of overwriting check
  336. fi
  337. echo shar: Extracting \"te_defs.h\" \(11866 characters\)
  338. if test -f te_defs.h ; then 
  339.   echo shar: Will not over-write existing file \"te_defs.h\"
  340. else
  341. sed "s/^X//" >te_defs.h <<'END_OF_te_defs.h'
  342. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  343. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  344. X/* They may be copied if this copyright notice is included                    */
  345. X
  346. X/* te_defs.h definitions file        1/9/87    */
  347. X
  348. X#include <stdio.h>
  349. X#include <ctype.h>
  350. X#include <sgtty.h>
  351. X#include <setjmp.h>
  352. X
  353. X#define CTL(x) (('x') & 0x1f)    /* for control chars                    */
  354. X#define ERROR(e) longjmp(xxx, (e))
  355. X#define BLOCKSIZE (0x10000 - 8)    /* size of memory block to allocate        */
  356. X#define CELLSIZE 256            /* number of characters per cell        */
  357. X#define CSTACKSIZE 64            /* size of command stack                */
  358. X#define MSTACKSIZE 64            /* size of macro stack                    */
  359. X#define QSTACKSIZE 64            /* size of q register stack                */
  360. X#define ESTACKSIZE 64            /* size of expression stack                */
  361. X#define TTIBUFSIZE 1024            /* size of type-ahead buffer            */
  362. X#define BUFF_LIMIT 16384        /* text buffer soft limit for ED & 4    */
  363. X#define NQREGS 36                /* number of Q registers                */
  364. X#define CBUFF 0                    /* id for command buffer                */
  365. X#define SERBUF NQREGS+1            /* and search string buffer                */
  366. X#define FILBUF NQREGS+2            /* and file string buffer                */
  367. X#define SYSBUF NQREGS+3            /* and system command buffer            */
  368. X#define TIMBUF NQREGS+4            /* and time/date buffer                    */
  369. X#define cbuf qreg[CBUFF]         /* shorthand for command-string header    */
  370. X#define sbuf qreg[SERBUF]        /* and for search-buffer header            */
  371. X#define fbuf qreg[FILBUF]        /* and for file-buffer header            */
  372. X#define sysbuf qreg[SYSBUF]        /* and for system command header        */
  373. X#define timbuf qreg[TIMBUF]        /* and for time/date header                */
  374. X#define cptr (*msp)                /* command string is top of macro stack    */
  375. X#define cmdstr mstack[0]         /* for entering command string            */
  376. X#define TAB 011                    /* define special chars                    */
  377. X#define LF 012
  378. X#define VT 013
  379. X#define FF 014
  380. X#define CR 015
  381. X#define ESC 033
  382. X#define DEL 0177
  383. X
  384. X/* expression operators */
  385. X#define OP_START 1
  386. X#define OP_ADD    2
  387. X#define OP_SUB    3
  388. X#define OP_MULT    4
  389. X#define OP_DIV    5
  390. X#define OP_AND    6
  391. X#define OP_OR    7
  392. X
  393. X/* macro flags */
  394. X#define F_ITER    1
  395. X
  396. X/* bits in special-character table */
  397. X#define A_S 1                    /* "skipto()" special character        */
  398. X#define A_T 2                    /* command with std text argument    */
  399. X#define A_E 4                    /* E<char> takes a text argument    */
  400. X#define A_F 8                    /* F<char> takes a text argument    */
  401. X#define A_X 16                    /* char causes "skipto()" to exit    */
  402. X#define A_Q 32                    /* command with q-register argument    */
  403. X#define A_A 64                    /* special char in search string    */
  404. X#define A_L 128                    /* character is a line separator    */
  405. X
  406. X/* error codes */
  407. X#define E_BNI 1
  408. X#define E_CPQ 2
  409. X#define E_COF 3
  410. X#define E_FNF 4
  411. X#define E_IEC 5
  412. X#define E_IFC 6
  413. X#define E_IIA 7
  414. X#define E_ILL 8
  415. X#define E_ILN 9
  416. X#define E_IPA 10
  417. X#define E_IQC 11
  418. X#define E_IQN 12
  419. X#define E_IRA 13
  420. X#define E_ISA 14
  421. X#define E_ISS 15
  422. X#define E_IUC 16
  423. X#define E_MEM 17
  424. X#define E_MRP 18
  425. X#define E_NAB 19
  426. X#define E_NAC 20
  427. X#define E_NAE 21
  428. X#define E_NAP 22
  429. X#define E_NAQ 23
  430. X#define E_NAS 24
  431. X#define E_NAU 25
  432. X#define E_NFI 26
  433. X#define E_NFO 27
  434. X#define E_NYA 28
  435. X#define E_OFO 29
  436. X#define E_PDO 30
  437. X#define E_POP 31
  438. X#define E_SNI 32
  439. X#define E_SRH 33
  440. X#define E_STL 34
  441. X#define E_UTC 35
  442. X#define E_UTM 36
  443. X#define E_XAB 37
  444. X#define E_YCA 38
  445. X#define E_IWA 39
  446. X#define E_NFR 40
  447. X#define E_INT 41
  448. X#define E_EFI 42
  449. X#define E_IAA 43
  450. X#define E_AMB 44
  451. X#define E_SYS 45
  452. X
  453. X/* define names for window control registers */
  454. X#define WN_type win_data[0]
  455. X#define WN_width win_data[1]
  456. X#define WN_height win_data[2]
  457. X#define WN_seeall win_data[3]
  458. X#define WN_mark win_data[4]
  459. X#define WN_hold win_data[5]
  460. X#define WN_origin win_data[6]
  461. X#define WN_scroll win_data[7]
  462. X
  463. X/* define display operations */
  464. X#define WIN_OFF 0            /* disable window    */
  465. X#define WIN_SUSP 1            /* suspend window    */
  466. X#define WIN_INIT 2            /* turn on window    */
  467. X#define WIN_RESUME 3        /* re-enable window    */
  468. X#define WIN_REFR 4            /* refresh window    */
  469. X#define WIN_LINE 5            /* display one line */
  470. X#define WIN_REDRAW 6        /* force window absolute redraw on next refresh */
  471. X#define WIN_DISP 7            /* refresh window even if not enabled */
  472. X
  473. X/* define scope special functions */
  474. X#define VT_CLEAR 0            /* clear screen */
  475. X#define VT_EEOL 1            /* erase to eol    */
  476. X#define VT_SETSPEC1 2        /* set special (reverse) video */
  477. X#define VT_SETSPEC2 3        /* alternative special video */
  478. X#define VT_CLRSPEC 4        /* clear it */
  479. X#define VT_BS1 5            /* backspace and erase 1 */
  480. X#define VT_BS2 6            /* backspace and erase 2 */
  481. X#define VT_LINEUP 7            /* up one line */
  482. X#define VT_EBOL 8            /* erase from bol */
  483. X
  484. X/* define keyboard modes */
  485. X#define TTY_OFF 0            /* final "off" */
  486. X#define TTY_SUSP 1            /* temporary suspend */
  487. X#define TTY_ON 2            /* initial "on" */
  488. X#define TTY_RESUME 3        /* resume after suspend */
  489. X
  490. X/* define values for ED, ET, EZ flags */
  491. X#define ED_CARET 1
  492. X#define ED_YPROT 2
  493. X#define ED_EXPMEM 4
  494. X#define ED_SFAIL 16
  495. X#define ED_SMULT 64
  496. X
  497. X#define ET_IMAGE 1
  498. X#define ET_NOECHO 8
  499. X#define ET_CTRLO 16
  500. X#define ET_NOWAIT 32
  501. X#define ET_QUIT 128
  502. X#define ET_TRUNC 256
  503. X#define ET_CTRLC 32768
  504. X
  505. X#define EZ_CRLF 1
  506. X#define EZ_READFF 2
  507. X#define EZ_TAB4 4
  508. X#define EZ_NOTMPFIL 8
  509. X#define EZ_NOTABI 16
  510. X#define EZ_NOVTFF 32
  511. X#define EZ_MULT 64
  512. X /* define buffer cell */
  513. X/* a buffer cell is a forward pointer, a backward pointer, */
  514. X/* and CELLSIZE characters */
  515. X
  516. Xstruct buffcell
  517. X    {
  518. X    struct buffcell *f;        /* forward pointer    */
  519. X    struct buffcell *b;        /* backward pointer    */
  520. X    char ch[CELLSIZE];        /* char storage        */
  521. X    };
  522. X
  523. X/* define structures for buffer header, q-register header,            */
  524. X/* q-register pointer, macro stack entry, and macro iteration list    */
  525. X/* these are really alternative ways of looking at the same cell    */
  526. X
  527. Xstruct qh            /* q-register header */
  528. X    {
  529. X    struct buffcell *f;    /* forward pointer */
  530. X    struct buffcell *b;    /* backward pointer */
  531. X    int z;                /* number of characters */
  532. X    int v;                /* q-register numeric value */
  533. X    } ;
  534. X
  535. Xstruct qp            /* q-register pointer/macro stack entry */
  536. X    {
  537. X    struct qp *f;        /* forward pointer */
  538. X    struct buffcell *p;    /* pointer to a buffer cell */
  539. X    int c;                /* character offset */
  540. X    int z;                /* number of characters in object pointed to */
  541. X    int dot;            /* current character position */
  542. X    int flag;            /* flags for "iteration in process," "ei macro," etc. */
  543. X    struct is *il;        /* iteration list pointer */
  544. X    int *condsp;        /* saved conditional stack pointer */
  545. X    } ;
  546. X
  547. Xstruct is            /* macro iteration list entry */
  548. X    {
  549. X    struct is *f;        /* forward pointer */
  550. X    struct is *b;        /* backward pointer */
  551. X    struct buffcell *p;    /* cell with start of iteration */
  552. X    int c;                /* char offset where iteration started */
  553. X    int dot;            /* char position where iteration started */
  554. X    int count;            /* iteration count */
  555. X    int dflag;            /* definite iteration flag */
  556. X    } ;
  557. X
  558. Xstruct ms            /* macro stack entry */ /* not used at present */
  559. X    {
  560. X    struct ms *f;        /* forward pointer */
  561. X    struct ms *b;        /* backward pointer */
  562. X    struct buffcell *p;    /* pointer to a buffer cell */
  563. X    int c;                /* character offset */
  564. X    struct is *il;        /* pointer to iteration list */
  565. X    } ;
  566. X
  567. Xstruct bh            /* buffer header list entry */
  568. X    {
  569. X    struct buffcell *f;    /* pointer to buffer */
  570. X    struct buffcell *b;    /* null pointer */
  571. X    int z;                /* number of characters */
  572. X    int v;                /* not used */
  573. X    struct bh *ff;        /* forward pointer */
  574. X    struct bh *bb;        /* backward pointer */
  575. X    } ;
  576. X
  577. X/* define expression stack entry */
  578. Xstruct exp_entry
  579. X    {
  580. X    int val1;        /* first value                            */
  581. X    int flag1;        /* nonzero if there is a first value    */
  582. X    int val2;        /* second value (set by 'comma')        */
  583. X    int flag2;        /* nonzero if there is one                */
  584. X    int exp;        /* expression in process                */
  585. X    int op;            /* operation to be applied                 */
  586. X    } ;
  587. X
  588. X/* define file data structures */
  589. Xstruct infiledata                /* structure of input file info */
  590. X    {
  591. X    FILE *fd;                        /* file pointer */
  592. X    int eofsw;                        /* end-of-file switch */
  593. X    } ;
  594. X
  595. Xstruct outfiledata                /* structure of output file info */
  596. X    {
  597. X    FILE *fd;                        /* file pointer */
  598. X    char f_name[CELLSIZE+5];        /* real name of output */
  599. X    char t_name[CELLSIZE+5];        /* temporary output name */
  600. X    int name_size;                    /* number of chars in name */
  601. X    int bak;                        /* backup flag */
  602. X    } ;
  603. X
  604. Xextern struct infiledata *infile;        /* pointer to currently active intput file structure */
  605. Xextern struct outfiledata *outfile;        /* pointer to currently active output file structure */
  606. Xextern struct outfiledata po_file, so_file;        /* output file descriptors */
  607. X /* define global variables, etc. */
  608. X
  609. Xextern int char_count;                    /* char count for tab typer            */
  610. Xextern char lastc;                        /* last char read                    */
  611. Xextern int ttyerr;                        /* error return from ioctl            */
  612. Xextern int errno;                        /* system error code                */
  613. Xextern struct sgttyb ttybuf;            /* local copy of tty control data    */
  614. Xextern int inp_noterm;                    /* nonzero if standard in is not a terminal    */
  615. Xextern int out_noterm;                    /* nonzero if standard out is not a term.    */
  616. Xextern jmp_buf xxx;                        /* preserved environment for error restart    */
  617. Xextern int err;                            /* local error code                    */
  618. Xextern struct qp t_qp;                    /* temporary buffer pointer            */
  619. Xextern struct qp aa, bb, cc;            /* more temporaries                    */
  620. Xextern struct buffcell t_bcell;            /* temporary bcell                    */
  621. Xextern int tabmask;                        /* mask for selecting 4/8 char tabs    */
  622. Xextern int exitflag;                    /* flag for ending command str exec    */
  623. Xextern char term_char;                    /* terminator for insert, search, etc.    */
  624. Xextern char cmdc;                        /* current command character        */
  625. Xextern char skipc;                        /* char found by "skipto()"            */
  626. Xextern int dot, z, tdot;                /* current, last, temp buffer position    */
  627. Xextern int ll, mm, nn;                    /* general temps                    */
  628. Xextern int ins_count;                    /* count of chars inserted            */
  629. Xextern int ctrl_e;                        /* form feed flag                    */
  630. Xextern int ctrl_r;                        /* current number radix (8, 10, 16)    */
  631. Xextern int ctrl_s;                        /* string length for S, I, G        */
  632. Xextern int ctrl_x;                        /* search case flag                    */
  633. Xextern int ed_val;                        /* ED value                            */
  634. Xextern int es_val;                        /* ES value                            */
  635. Xextern int et_val;                        /* ET value                            */
  636. Xextern int eu_val;                        /* EU value                            */
  637. Xextern int ev_val;                        /* EV value                            */
  638. Xextern int ez_val;                        /* EZ value                            */
  639. Xextern int srch_result;                    /* result of last :S executed        */
  640. Xextern int atflag;                        /* flag for @ char typed            */
  641. Xextern int colonflag;                    /* flag for : char typed            */
  642. Xextern int trace_sw;                    /* nonzero if tracing command exec    */
  643. X
  644. Xextern int win_data[];                    /* window control parameters        */
  645. Xextern struct buffcell *insert_p;        /* pointer to temp text buffer during insert */
  646. Xextern int buff_mod;                    /* set to earliest buffer change    */
  647. Xextern int search_flag;                    /* set nonzero by search            */
  648. X
  649. Xextern char *errors[];                    /* error text                        */
  650. Xextern char mapch[], mapch_l[];            /* char mapping tables                */
  651. Xextern char spec_chars[];                /* special character table            */
  652. X
  653. Xextern char skipto(), find_endcond(), getcmdc(), getcmdc0();    /* routines that return chars */
  654. X
  655. Xextern FILE *eisw;                        /* indirect command file pointer    */
  656. Xextern FILE *fopen();
  657. X
  658. Xextern struct buffcell *freebuff;        /* buffcell free-list pointer    */
  659. Xextern struct buffcell *dly_freebuff;    /* delayed free-list pointer    */
  660. Xextern struct qp *freedcell;            /* cell free-list pointer        */
  661. Xextern struct buffcell *get_bcell();    /* get buffcell routine            */
  662. Xextern struct qp *get_dcell();            /* get data cell routine        */
  663. X
  664. X/* the text buffer header */
  665. Xextern struct qh buff;
  666. X
  667. X/* the q-register headers point to the start of the buffer and registers */
  668. Xextern struct qh qreg[];            /* for q regs, command, search, file */
  669. X
  670. X/* the q-register stack contains temporary copies of q-register contents */
  671. Xextern struct qh qstack[];            /* q-reg stack */
  672. Xextern struct qh *qsp;                /* q-reg stack pointer */
  673. X
  674. X/* the macro stack contains pointers to the currently active macros. */
  675. X/* the top of the stack is the command pointer */
  676. Xextern struct qp mstack[];            /* macro stack */
  677. Xextern struct qp *msp;                /* macro stack pointer */
  678. X
  679. X/* the expression stack */
  680. Xextern struct exp_entry estack[];    /* expression stack */
  681. Xextern struct exp_entry *esp;        /* expression stack pointer */
  682. X
  683. END_OF_te_defs.h
  684. if test 11866 -ne `wc -c <te_defs.h`; then
  685.     echo shar: \"te_defs.h\" unpacked with wrong size!?
  686. fi
  687. # end of overwriting check
  688. fi
  689. echo shar: Extracting \"te_srch.c\" \(14562 characters\)
  690. if test -f te_srch.c ; then 
  691.   echo shar: Will not over-write existing file \"te_srch.c\"
  692. else
  693. sed "s/^X//" >te_srch.c <<'END_OF_te_srch.c'
  694. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  695. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  696. X/* They may be copied if this copyright notice is included                    */
  697. X
  698. X/* te_srch.c   routines associated with search operations   2/5/86 */
  699. X#include "te_defs.h"
  700. X
  701. X/* routine to read in a string with string-build characters */
  702. X/* used for search, tag, file name operations                */
  703. X/* returns 0 if empty string entered, nonzero otherwise        */
  704. X
  705. Xint build_string(buff)
  706. X    struct qh *buff;            /* arg is addr of q-reg header */
  707. X    {
  708. X    int count;                    /* char count */
  709. X    struct buffcell *tp;        /* pointer to temporary string */
  710. X    char c;                        /* temp character */
  711. X
  712. X    term_char = (atflag) ? getcmdc(trace_sw) : ESC;        /* read terminator */
  713. X    count = atflag = 0;            /* initialize char count */
  714. X    if (!peekcmdc(term_char))    /* if string is not empty */
  715. X        {
  716. X
  717. X/* create a temporary string and read chars into it until the terminator */
  718. X        for (tp = bb.p = get_bcell(), bb.c = 0; (c = getcmdc(trace_sw)) != term_char; )
  719. X            {
  720. X            if ((c == '^') && !(ed_val & ED_CARET))        /* read next char as CTL */
  721. X                {
  722. X                if ((c = getcmdc(trace_sw)) == term_char) ERROR(msp <= &mstack[0] ? E_UTC : E_UTM);
  723. X                c &= 0x1f;
  724. X                }
  725. X            if ((c &= 0177) < ' ')            /* if a control char */
  726. X                {
  727. X                switch (c)
  728. X                    {
  729. X                    case CTL (Q):            /* take next char literally */
  730. X                    case CTL (R):
  731. X                        if ((c = getcmdc(trace_sw)) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  732. X                        break;                /* fetch character and go store */
  733. X
  734. X                    case CTL (V):            /* take next char as lower case */
  735. X                        if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  736. X                        c = mapch_l[cmdc];
  737. X                        break;
  738. X
  739. X                    case CTL (W):            /* take next char as upper case */
  740. X                        if ((c = getcmdc(trace_sw)) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  741. X                        if (islower(c)) c = toupper(c);
  742. X                        break;
  743. X
  744. X                    case CTL (E):            /* expanded constructs */
  745. X                        if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  746. X                        switch (mapch_l[cmdc])
  747. X                            {
  748. X                            case 'u':        /* use char in q-reg */
  749. X                                if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  750. X                                c = qreg[getqspec(1, cmdc)].v & 0x7f;
  751. X                                break;
  752. X
  753. X                            case 'q':        /* use string in q-reg */
  754. X                                if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  755. X                                ll = getqspec(1, cmdc);            /* read the reg spec */
  756. X                                aa.p = qreg[ll].f;                /* set a pointer to it */
  757. X                                aa.c = 0;
  758. X                                for (mm = 0; mm < qreg[ll].z; mm++)
  759. X                                    {
  760. X                                    bb.p->ch[bb.c] = aa.p->ch[aa.c];        /* store char */
  761. X                                    fwdcx(&bb);                    /* store next char */
  762. X                                    fwdc(&aa);
  763. X                                    ++count;
  764. X                                    }
  765. X                                continue;                /* repeat loop without storing */
  766. X
  767. X                            default:
  768. X                                bb.p->ch[bb.c] = CTL (E);        /* not special: store the ^E */
  769. X                                fwdcx(&bb);
  770. X                                ++count;
  771. X                                c = cmdc;                        /* and go store the following char */
  772. X                                break;
  773. X
  774. X                            }                            /* end ^E switch */
  775. X                        }                            /* end outer switch */
  776. X                }                            /* end "if a control char */
  777. X            bb.p->ch[bb.c] = c;            /* store character */
  778. X            fwdcx(&bb);                    /* advance pointer */
  779. X            ++count;                    /* count characters */
  780. X            }                        /* end "for" loop */
  781. X        free_blist(buff->f);        /* return old buffer */
  782. X        buff->f = tp;                /* put in new one */
  783. X        buff->f->b = (struct buffcell *) buff;
  784. X        buff->z = count;            /* store count of chars in string */
  785. X        }                    /* end non-null string */
  786. X    else getcmdc(trace_sw);        /* empty string: consume terminator */
  787. X    return(count);            /* return char count */
  788. X    }            
  789. X
  790. X
  791. X
  792. X
  793. X/* routine to handle end of a search operation    */
  794. X/* called with pass/fail result from search        */
  795. X/* returns same pass/fail result                */
  796. X
  797. Xint end_search(result)
  798. X    int result;
  799. X    {
  800. X    if (!result)        /* if search failed */
  801. X        {
  802. X        if (!(esp->flag2 || (ed_val & ED_SFAIL))) dot = 0;        /* if an unbounded search failed, clear ptr */
  803. X        if (!colonflag && !peekcmdc(';')) ERROR(E_SRH);        /* if no real or implied colon, error if failure */
  804. X        }
  805. X    esp->flag1 = colonflag;                /* return a value if a :S command */
  806. X    srch_result = esp->val1 = result;    /* and leave it for next ";" */
  807. X    esp->flag2 = colonflag = atflag = 0;    /* consume arguments */
  808. X    esp->op = OP_START;
  809. X    return(result);
  810. X    }
  811. X
  812. X/* routine to set up for search operation */
  813. X/* reads search arguments, returns search count */
  814. X
  815. Xstatic struct qp sm, sb;        /* match-string and buffer pointers */
  816. Xstatic char *pmap;                /* pointer to character mapping table */
  817. Xstatic int locb;                /* reverse search limit */
  818. Xstatic int last_z;                /* end point for reverse search */
  819. X
  820. Xint setup_search()
  821. X    {
  822. X    int count;                /* string occurrence counter */
  823. X
  824. X    set_pointer(dot, &aa);            /* set a pointer to start of search */
  825. X    if (colonflag >= 2) esp->flag2 = esp->flag1 = esp->val2 = esp->val1 = 1;    /* ::S is 1,1S */
  826. X    if ((count = get_value(1)) == 0) ERROR(E_ISA);     /* read search count: default is 1 */
  827. X    else if (count > 0)                /* search forward */
  828. X        {
  829. X        if (esp->flag2)        /* if bounded search */
  830. X            {
  831. X            if (esp->val2 < 0) esp->val2 = -(esp->val2);    /* set limit */
  832. X            if ((aa.z = dot + esp->val2) > z) aa.z = z;        /* or z, whichever less */
  833. X            }
  834. X        else aa.z = z;
  835. X        }
  836. X    else
  837. X        {
  838. X        if (esp->flag2)        /* if bounded search */
  839. X            {
  840. X            if (esp->val2 < 0) esp->val2 = -(esp->val2);    /* set limit */
  841. X            if ((locb = dot - esp->val2) < 0) locb = 0;        /* or 0, whichever greater */
  842. X            }
  843. X        else locb = 0;
  844. X        }
  845. X    return(count);
  846. X    }
  847. X
  848. X/* routine to do N, _, E_ searches:  search, if search fails, then get    */
  849. X/* next page and continue                                                 */
  850. X
  851. Xdo_nsearch(arg)
  852. X    char arg;        /* arg is 'n', '_', or 'e' to define which search */
  853. X    {
  854. X    int scount;        /* search count */
  855. X
  856. X    build_string(&sbuf);            /* read the search string */
  857. X    if ((scount = get_value(1)) <= 0) ERROR(E_ISA);        /* count must be >0 */
  858. X    set_pointer(dot, &aa);            /* start search at dot */
  859. X    esp->flag2 = locb = 0;            /* make it unbounded */
  860. X
  861. X    while (scount > 0)                /* search until found */
  862. X        {
  863. X        if (!do_search(1))            /* search forwards */
  864. X            {                        /*   if search fails... */
  865. X            if (infile->eofsw || !infile->fd) break;    /* if no input, quit */
  866. X            if (arg == 'n')
  867. X                {
  868. X                set_pointer(0, &aa);    /* write file if 'n' */
  869. X                write_file(&aa, z, ctrl_e);
  870. X                }
  871. X
  872. X            /* not 'n': if _, and an output file, and data to lose, error */
  873. X            else if ((arg == '_') && (outfile->fd) && (z) && (ed_val & ED_YPROT)) ERROR(E_YCA);
  874. X
  875. X            buff_mod = dot = z = 0;                /* clear buffer */
  876. X            set_pointer(0, &aa);
  877. X            read_file(&aa, &z, (ed_val & ED_EXPMEM ? -1 : 0) );            /* read next page */
  878. X            set_pointer(0, &aa);        /* search next page from beginning */
  879. X            }
  880. X        else --scount;                    /* search successful: one fewer to look for */
  881. X        }
  882. X    return( end_search( (scount == 0) ? -1 : 0) );        /* use end_search to clean up */
  883. X    }
  884. X
  885. X
  886. X/* routine to do "FB" search - m,nFB is search from m to n,    */
  887. X/* nFB is search from . to nth line                            */
  888. X/* convert arguments to args of normal m,nS command            */
  889. X
  890. Xint do_fb()                /* returns search result */
  891. X    {
  892. X    if (esp->flag1 && esp->flag2)    /* if two arguments */
  893. X        {
  894. X        dot = esp->val2;                        /* start from "m" arg */
  895. X        esp->val2 = esp->val1 - esp->val2;        /* get number of chars */
  896. X        }
  897. X    else                            /* if no or one args, treat as number of lines */
  898. X        {
  899. X        esp->val2 = lines(get_value(1));        /* number of chars */
  900. X        esp->flag2 = esp->flag1 = 1;            /* conjure up two args */
  901. X        }
  902. X    esp->val1 = (esp->val2 > 0) ? 1 : -1;    /* set search direction */
  903. X
  904. X    build_string(&sbuf);        /* read search string and terminator */
  905. X    return(end_search(  do_search( setup_search() )  ));    /* do search and return result */
  906. X    }
  907. X
  908. X/* routine to do search operation: called with search count as argument */
  909. X/* returns -1 (pass) or 0 (fail)                                        */
  910. X
  911. Xint do_search(count)
  912. X    int count;
  913. X    {
  914. X    pmap = (ctrl_x) ? &mapch[0] : &mapch_l[0];        /* set approp. mapping table */
  915. X    sm.z = sbuf.z;                    /* copy # of chars in search buffer */
  916. X
  917. X    if (count > 0)
  918. X        {
  919. X        for (sm.dot = 0; count > 0; count--)     /* loop to count occurrences */
  920. X            {
  921. X            for (; aa.dot < aa.z; aa.dot++)     /* loop to advance search pointer */
  922. X                {
  923. X                for (sb.p = aa.p, sb.c = aa.c, sb.dot = aa.dot, sm.p = sbuf.f, sm.dot = sm.c = 0;
  924. X                                            (sb.dot < z) && (sm.dot < sm.z); sm.dot++, sb.dot++)
  925. X                    {                                /* for each char in search string */
  926. X                    if (spec_chars[ sm.p->ch[sm.c] ] & A_A)        /* if search string char is "special" */
  927. X                        {
  928. X                        if (!srch_cmp()) break;            /* then use expanded comparison routine */
  929. X                        }
  930. X                    else if (*(pmap + sb.p->ch[sb.c]) != *(pmap + sm.p->ch[sm.c])) break;        /* else just compare */
  931. X                    if (++sm.c > CELLSIZE-1)        /* advance search-string ptr */
  932. X                        {
  933. X                        sm.p = sm.p->f;
  934. X                        sm.c = 0;
  935. X                        }
  936. X                    if (++sb.c > CELLSIZE-1)        /* advance buffer ptr */
  937. X                        {
  938. X                        sb.p = sb.p->f;
  939. X                        sb.c = 0;
  940. X                        }
  941. X                    }                    /* end comparison loop */
  942. X
  943. X                if (sm.dot >= sm.z) break;            /* exit if found */
  944. X                if (++aa.c > CELLSIZE-1)            /* else not found: advance buffer pointer */
  945. X                    {
  946. X                    aa.p = aa.p->f;
  947. X                    aa.c = 0;
  948. X                    }
  949. X                }                        /* end search loop */
  950. X
  951. X            if (sm.dot < sm.z) break;                /* if one search failed, don't do more */
  952. X            else
  953. X                {
  954. X                ctrl_s = aa.dot - sb.dot;            /* otherwise save -length of string found */
  955. X                if ((ed_val & ED_SMULT) && (count > 1))        /* if funny "advance by 1" mode */
  956. X                    {
  957. X                    ++aa.dot;                        /* advance buffer pointer by one only */
  958. X                    if (++aa.c > CELLSIZE-1)
  959. X                        {
  960. X                        aa.p = aa.p->f;
  961. X                        aa.c = 0;
  962. X                        }
  963. X                    }
  964. X                 else
  965. X                    {
  966. X                    aa.dot = sb.dot;                /* advance search pointer past string */
  967. X                    aa.p = sb.p;
  968. X                    aa.c = sb.c;
  969. X                    }
  970. X                }
  971. X            }                    /* end "search n times" */
  972. X        }                /* end "search forwards" */
  973. X
  974. X    else                 /* search backwards */
  975. X        {
  976. X        for (last_z = z, sm.dot = 0; count < 0; count++)     /* loop to count occurrences */
  977. X            {
  978. X            for (; aa.dot >= locb; aa.dot--)     /* loop to advance (backwards) search pointer */
  979. X                {
  980. X                for (sb.p = aa.p, sb.c = aa.c, sb.dot = aa.dot, sm.p = sbuf.f, sm.dot = sm.c = 0;
  981. X                                                (sb.dot < last_z) && (sm.dot < sm.z); sm.dot++, sb.dot++)
  982. X                    {                                /* loop to compare string */
  983. X                    if (spec_chars[ sm.p->ch[sm.c] ] & A_A)        /* if search string char is "special" */
  984. X                        {
  985. X                        if (!srch_cmp()) break;        /* then use expanded comparison routine */
  986. X                        }
  987. X                    else if (*(pmap + sb.p->ch[sb.c]) != *(pmap + sm.p->ch[sm.c])) break;        /* else just compare */
  988. X                    if (++sm.c > CELLSIZE-1)        /* advance search-string ptr */
  989. X                        {
  990. X                        sm.p = sm.p->f;
  991. X                        sm.c = 0;
  992. X                        }
  993. X                    if (++sb.c > CELLSIZE-1)        /* advance buffer ptr */
  994. X                        {
  995. X                        sb.p = sb.p->f;
  996. X                        sb.c = 0;
  997. X                        }
  998. X                    }                    /* end comparison loop */
  999. X                if (sm.dot >= sm.z)                    /* search matches: */
  1000. X                    {
  1001. X                    if (!(ed_val & ED_SMULT)) last_z = aa.dot;    /* set last_z to point where this string was found */
  1002. X                    break;
  1003. X                    }
  1004. X                if (sb.dot >= last_z)                /* or if string is beyond end of buffer */
  1005. X                    {
  1006. X                    sm.dot = sm.z;                        /* make search appear to have succeeded */
  1007. X                    --count;                            /* so as to back up pointer, and force one more look */
  1008. X                    break;
  1009. X                    }
  1010. X                if (--aa.c < 0)                /* else advance buffer pointer (backwards) */
  1011. X                    {
  1012. X                    aa.p = aa.p->b;
  1013. X                    aa.c = CELLSIZE-1;
  1014. X                    }
  1015. X                }                        /* end search loop */
  1016. X            if (sm.dot < sm.z) break;                /* if one search failed, don't do more */
  1017. X            else
  1018. X                {
  1019. X                if (count < -1) backc(&aa);            /* if this is not last search, back pointer up one */
  1020. X                else                    
  1021. X                    {
  1022. X                    ctrl_s = aa.dot - sb.dot;        /* otherwise save -length of string found */
  1023. X                    aa.dot = sb.dot;                /* advance pointer past string */
  1024. X                    aa.p = sb.p;
  1025. X                    aa.c = sb.c;
  1026. X                    }
  1027. X                }
  1028. X            }                    /* end "search n times" */
  1029. X        }                /* end "search backwards" */
  1030. X    if (sm.dot >= sm.z) dot = aa.dot;                /* if search succeeded, update pointer    */
  1031. X    search_flag = 1;                                /* set "search occurred" (for ES)        */
  1032. X    return((sm.dot >= sm.z) ? -1 : 0);                /* and return -1 (pass) or 0 (fail)        */
  1033. X    }                /* end "do_search" */
  1034. X
  1035. X/* expanded search comparison */
  1036. X/* returns 1 if match, 0 if not */
  1037. X
  1038. Xint srch_cmp()
  1039. X    {
  1040. X    int tq;                        /* q-reg name for ^EGq */
  1041. X    struct qp tqp;                /* pointer to read q reg */
  1042. X
  1043. X    switch (mapch_l[sm.p->ch[sm.c]])        /* what is search character */
  1044. X        {
  1045. X        case CTL (N):                /* match anything but following construct */
  1046. X            if (sm.dot >= sm.z) ERROR(E_ISS);    /* don't read past end of string */
  1047. X            fwdc(&sm);                /* skip the ^N */
  1048. X            return(!srch_cmp());
  1049. X
  1050. X        case CTL (X):                /* match any character */
  1051. X            return(1);
  1052. X
  1053. X        case CTL (Q):                /* take next char literally */
  1054. X        case CTL (R):
  1055. X            if (sm.dot >= sm.z) ERROR(E_ISS);    /* don't read past end of string */
  1056. X            fwdc(&sm);                /* skip the ^Q */
  1057. X            return(*(pmap + sb.p->ch[sb.c]) == *(pmap + sm.p->ch[sm.c]));
  1058. X
  1059. X        case CTL (S):                /* match any nonalphanumeric */
  1060. X            return(!isalnum(sb.p->ch[sb.c]));
  1061. X
  1062. X        case CTL (E):
  1063. X            if (sm.dot >= sm.z) ERROR(E_ISS);    /* don't read past end of string */
  1064. X            fwdc(&sm);                /* skip the ^E */
  1065. X            switch (mapch_l[sm.p->ch[sm.c]])
  1066. X                {
  1067. X                case 'a':            /* match any alpha */
  1068. X                    return(isalpha(sb.p->ch[sb.c]));
  1069. X
  1070. X                case 'b':            /* match any nonalpha */
  1071. X                    return(!isalnum(sb.p->ch[sb.c]));
  1072. X
  1073. X                case 'c':            /* rad50 symbol constituent */
  1074. X                    return(!isalnum(sb.p->ch[sb.c]) || (sb.p->ch[sb.c] == '$') || (sb.p->ch[sb.c] == '.'));
  1075. X
  1076. X                case 'd':            /* digit */
  1077. X                    return(isdigit(sb.p->ch[sb.c]));
  1078. X
  1079. X                case 'l':            /* line terminator LF, VT, FF */
  1080. X                    return((sb.p->ch[sb.c] == LF) || (sb.p->ch[sb.c] == FF) || (sb.p->ch[sb.c] == VT));
  1081. X
  1082. X                case 'r':            /* alphanumeric */
  1083. X                    return(isalnum(sb.p->ch[sb.c]));
  1084. X
  1085. X                case 'v':            /* lower case */
  1086. X                    return(islower(sb.p->ch[sb.c]));
  1087. X
  1088. X                case 'w':            /* upper case */
  1089. X                    return(isupper(sb.p->ch[sb.c]));
  1090. X
  1091. X                case 's':            /* any non-null string of spaces or tabs */
  1092. X                    if (((sb.p->ch[sb.c]&0177) != ' ') && ((sb.p->ch[sb.c]&0177) != TAB)) return(0);    /* failure */
  1093. X                    /* skip remaining spaces or tabs */
  1094. X                    for ( fwdc(&sb); ((sb.p->ch[sb.c]&0177) == ' ') || ((sb.p->ch[sb.c]&0177) == TAB); fwdc(&sb) );
  1095. X                    backc(&sb);        /* back up one char (calling routine will skip it) */
  1096. X                    return(1);        /* success */
  1097. X
  1098. X                case 'g':            /* any char in specified q register */
  1099. X                    if (sm.dot >= sm.z) ERROR(E_ISS);    /* don't read past end of string */
  1100. X                    fwdc(&sm);        /* get to the next char */
  1101. X                    tq = getqspec(1, sm.p->ch[sm.c]);        /* read q-reg spec */                    
  1102. X                    for (tqp.dot = tqp.c = 0, tqp.p = qreg[tq].f; tqp.dot < qreg[tq].z; fwdc(&tqp))
  1103. X                        if (*(pmap + tqp.p->ch[tqp.c]) == *(pmap + sb.p->ch[sb.c])) return(1);    /* match */
  1104. X                    return(0);        /* fail */
  1105. X
  1106. X                default:
  1107. X                    ERROR(E_ISS);
  1108. X                }                            /* end ^E constructions */
  1109. X
  1110. X        default:
  1111. X            return(*(pmap + sb.p->ch[sb.c]) == *(pmap + sm.p->ch[sm.c]));
  1112. X        }                                    /* end other constructions */
  1113. X    }
  1114. X
  1115. END_OF_te_srch.c
  1116. if test 14562 -ne `wc -c <te_srch.c`; then
  1117.     echo shar: \"te_srch.c\" unpacked with wrong size!?
  1118. fi
  1119. # end of overwriting check
  1120. fi
  1121. echo shar: Extracting \"te_subs.c\" \(13995 characters\)
  1122. if test -f te_subs.c ; then 
  1123.   echo shar: Will not over-write existing file \"te_subs.c\"
  1124. else
  1125. sed "s/^X//" >te_subs.c <<'END_OF_te_subs.c'
  1126. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  1127. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  1128. X/* They may be copied if this copyright notice is included                    */
  1129. X
  1130. X/* te_subs.c subroutines  11/8/85 */
  1131. X#include "te_defs.h"
  1132. X
  1133. X/* routines to copy a string of characters        */
  1134. X/* movenchars(from, to, n)                        */
  1135. X/*      from, to are the addresses of qps        */
  1136. X/*    n is the number of characters to move        */
  1137. X/* moveuntil(from, to, c, &n, max)                */
  1138. X/*      c is the match character that ends the move */
  1139. X/*    n is the returned number of chars moved    */
  1140. X/* max is the maximum number of chars to move    */
  1141. X
  1142. Xmovenchars(from, to, n)
  1143. X    struct qp *from, *to;        /* address of buffer pointers */
  1144. X    register int n;                /* number of characters */
  1145. X    {
  1146. X    register struct buffcell *fp, *tp;    /* local qp ".p" pointers    */
  1147. X    register int fc, tc;                /* local qp ".c" subscripts */
  1148. X
  1149. X    if (n != 0)
  1150. X        {
  1151. X        fp = from->p;                /* copy pointers to local registers */
  1152. X        fc = from->c;
  1153. X        tp = to->p;
  1154. X        tc = to->c;
  1155. X
  1156. X        for (; n > 0; n--)
  1157. X            {
  1158. X            tp->ch[tc++] = fp->ch[fc++];    /* move one char */
  1159. X
  1160. X            if (tc > CELLSIZE-1)    /* check current cell done */
  1161. X                {
  1162. X                if (!tp->f)        /* is there another following? */
  1163. X                    {
  1164. X                    tp->f = get_bcell();    /* no, add one */
  1165. X                    tp->f->b = tp;
  1166. X                    }
  1167. X                tp = tp->f;
  1168. X                tc = 0;
  1169. X                }
  1170. X
  1171. X            if (fc > CELLSIZE-1)    /* check current cell done */
  1172. X                {
  1173. X                if (!fp->f)        /* oops, run out of source */
  1174. X                    {
  1175. X                    if (n > 1) ERROR(E_UTC);    /* error if not done */
  1176. X                    }
  1177. X                else {
  1178. X                    fp = fp->f;        /* chain to next cell */
  1179. X                    fc = 0;
  1180. X                    }
  1181. X                }
  1182. X            }
  1183. X        from->p = fp;        /* restore arguments */
  1184. X        to->p = tp;
  1185. X        from->c = fc;
  1186. X        to->c = tc;
  1187. X        }
  1188. X    }
  1189. X moveuntil(from, to, c, n, max, trace)
  1190. X    struct qp *from, *to;        /* address of buffer pointers    */
  1191. X    register char c;            /* match char that ends move    */
  1192. X    int *n;                        /* pointer to returned value    */
  1193. X    int max;                    /* limit on chars to move        */
  1194. X    int trace;                    /* echo characters if nonzero    */
  1195. X    {
  1196. X    register struct buffcell *fp, *tp;    /* local qpr ".p" pointers    */
  1197. X    register int fc, tc;                /* local qpr ".c" subscripts */
  1198. X
  1199. X    fp = from->p;                /* copy pointers to local registers */
  1200. X    fc = from->c;
  1201. X    tp = to->p;
  1202. X    tc = to->c;
  1203. X
  1204. X    for (*n = 0; fp->ch[fc] != c; (*n)++)    /* until terminating char... */
  1205. X        {
  1206. X        if (max-- <= 0) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  1207. X        tp->ch[tc++] = fp->ch[fc++];    /* move one char */
  1208. X        if (trace) type_char(tp->ch[tc-1]);        /* type it out if trace mode */
  1209. X
  1210. X        if (tc > CELLSIZE-1)    /* check current cell done */
  1211. X            {
  1212. X            if (!tp->f)        /* is there another following? */
  1213. X                {
  1214. X                tp->f = get_bcell();    /* no, add one */
  1215. X                tp->f->b = tp;
  1216. X                }
  1217. X            tp = tp->f;
  1218. X            tc = 0;
  1219. X            }
  1220. X
  1221. X        if (fc > CELLSIZE-1)    /* check current cell done */
  1222. X            {
  1223. X            if (!fp->f) ERROR(E_UTC);     /* oops, run out of source */
  1224. X            else {
  1225. X                fp = fp->f;        /* chain to next cell */
  1226. X                fc = 0;
  1227. X                }
  1228. X            }
  1229. X        }
  1230. X
  1231. X    from->p = fp;        /* restore arguments */
  1232. X    to->p = tp;
  1233. X    from->c = fc;
  1234. X    to->c = tc;
  1235. X    }
  1236. X
  1237. X/* routine to get numeric argument */
  1238. Xint get_value(d)        /* get a value, default is argument */
  1239. X    int d;
  1240. X    {
  1241. X    int v;
  1242. X
  1243. X    v = (esp->flag1) ? esp->val1 : 
  1244. X            (esp->op == OP_SUB) ? -d : d;
  1245. X    esp->flag1 = 0;        /* consume argument */
  1246. X    esp->op = OP_START;
  1247. X    return(v);
  1248. X    }
  1249. X
  1250. X
  1251. X
  1252. X
  1253. X/* routine to convert a line count */
  1254. X/* returns number of chars between dot and nth line feed */
  1255. X
  1256. Xint lines(arg)
  1257. X    register int arg;
  1258. X    {
  1259. X    register int i, c;
  1260. X    register struct buffcell *p;
  1261. X
  1262. X    for (i = dot / CELLSIZE, p = buff.f; (i > 0) && (p->f); i--) p = p->f;    /* find dot */
  1263. X    c = dot % CELLSIZE;
  1264. X    if (arg <= 0)                /* scan backwards */
  1265. X        {
  1266. X        for (i = dot; (arg < 1) && (i > 0); )        /* repeat for each line */
  1267. X            {
  1268. X            --i;                /* count characters */
  1269. X            if (--c < 0)    /* back up the pointer */
  1270. X                {
  1271. X                if (!(p = p->b)) break;
  1272. X                c = CELLSIZE - 1;
  1273. X                }
  1274. X            if ( (ez_val & EZ_NOVTFF) ? (p->ch[c] == LF) : (spec_chars[p->ch[c]] & A_L) ) ++arg;    /* if line sep found */
  1275. X            }
  1276. X        if (arg > 0) ++i;                /* if terminated on a line separator, advance over the separator */
  1277. X        }
  1278. X
  1279. X    else                        /* scan forwards */
  1280. X        {
  1281. X        for (i = dot; (arg > 0) && (i < z); i++)
  1282. X            {
  1283. X            if ( (ez_val & EZ_NOVTFF) ? (p->ch[c] == LF) : (spec_chars[p->ch[c]] & A_L) ) --arg;
  1284. X            if (++c > CELLSIZE-1)
  1285. X                {
  1286. X                if (!(p = p->f)) break;
  1287. X                c = 0;
  1288. X                }
  1289. X            }            /* this will incr over the separator anyway */
  1290. X        }
  1291. X    return(i - dot);
  1292. X    }
  1293. X
  1294. X/* routine to handle args for K, T, X, etc.        */
  1295. X/* if two args, 'char x' to 'char y'            */
  1296. X/* if just one arg, then n lines (default 1)    */
  1297. X/* sets a pointer to the beginning of the specd    */
  1298. X/* string, and a char count value                */
  1299. X
  1300. Xint line_args(d, p)
  1301. X    int d;                    /* nonzero: leave dot at start */
  1302. X    struct qp *p;
  1303. X    {
  1304. X    int n;
  1305. X
  1306. X    if (esp->flag1 && esp->flag2)        /* if two args */
  1307. X        {
  1308. X        if (esp->val1 <= esp->val2)        /* in right order */
  1309. X            {
  1310. X            if (esp->val1 < 0) esp->val1 = 0;
  1311. X            if (esp->val2 > z) esp->val2 = z;
  1312. X            if (d) dot = esp->val1;        /* update dot */
  1313. X            set_pointer(esp->val1, p);    /* set the pointer */
  1314. X            esp->flag2 = esp->flag1 = 0;    /* consume arguments */
  1315. X            esp->op = OP_START;
  1316. X            return(esp->val2 - esp->val1);    /* and return the count */
  1317. X            }
  1318. X        else
  1319. X            {
  1320. X            if (esp->val2 < 0) esp->val2 = 0;
  1321. X            if (esp->val1 > z) esp->val1 = z;
  1322. X            if (d) dot = esp->val2;        /* update dot */
  1323. X            set_pointer(esp->val2, p);    /* args in reverse order */
  1324. X            esp->flag2 = esp->flag1 = 0;    /* consume arguments */
  1325. X            esp->op = OP_START;
  1326. X            return(esp->val1 - esp->val2);
  1327. X            }
  1328. X        }
  1329. X    else
  1330. X        {
  1331. X        n = lines(get_value(1));
  1332. X        if (n < -dot) n = -dot;
  1333. X        else if (n > z-dot) n = z-dot;
  1334. X        if (n >= 0) set_pointer(dot, p);
  1335. X        else
  1336. X            {
  1337. X            n = -n;
  1338. X            set_pointer(dot - n, p);
  1339. X            if (d) dot -= n;
  1340. X            }
  1341. X        return(n);
  1342. X        }
  1343. X    }
  1344. X
  1345. X/* convert character c to a q-register spec */
  1346. Xint getqspec(fors, c)    /* fors ("file or search") nonzero = allow _ or * */
  1347. X    int fors;
  1348. X    char c;
  1349. X    {
  1350. X    if (isdigit(c)) return(c - '0' + 1);
  1351. X    else if isalpha(c) return(mapch_l[c] - 'a' + 11);
  1352. X    else if (fors)
  1353. X        {
  1354. X        if (c == '_') return (SERBUF);
  1355. X        if (c == '*') return (FILBUF);
  1356. X        if (c == '%') return (SYSBUF);
  1357. X        if (c == '#') return (TIMBUF);
  1358. X        }
  1359. X    ERROR(E_IQN);
  1360. X    }
  1361. X
  1362. X
  1363. X
  1364. X/* routines to do insert operations */
  1365. X/* insert1() copies current cell up to dot into a new cell */
  1366. X/* leaves bb pointing to end of that text */
  1367. X/* insert2() copies rest of buffer */
  1368. X
  1369. Xstruct buffcell *insert_p;
  1370. X
  1371. Xinsert1()
  1372. X    {
  1373. X    int nchars;                /* number of chars in cell */
  1374. X
  1375. X    set_pointer(dot, &aa);    /* convert dot to a qp */
  1376. X    if (dot < buff_mod) buff_mod = dot;        /* update earliest char loc touched */
  1377. X    insert_p = bb.p = get_bcell();        /* get a new cell */
  1378. X    bb.c = 0;
  1379. X    nchars = aa.c;            /* save char position of dot in cell */
  1380. X    aa.c = 0;
  1381. X
  1382. X/* now aa points to the beginning of the buffer cell that */
  1383. X/* contains dot, bb points to the beginning of a new cell,*/
  1384. X/* nchars is the number of chars before dot */
  1385. X
  1386. X    movenchars(&aa, &bb, nchars);    /* copy cell up to dot */
  1387. X    }
  1388. X
  1389. X
  1390. X
  1391. Xinsert2(count)                /* count is the number of chars added */
  1392. X    int count;
  1393. X    {
  1394. X    aa.p->b->f = insert_p;        /* put the new cell where the old one was */
  1395. X    insert_p->b = aa.p->b;
  1396. X    insert_p = NULL;
  1397. X
  1398. X    bb.p->f = aa.p;            /* splice rest of buffer to end */
  1399. X    aa.p->b = bb.p;
  1400. X    movenchars(&aa, &bb, z-dot);    /* squeeze buffer */
  1401. X    free_blist(bb.p->f);    /* return unused cells */
  1402. X    bb.p->f = NULL;            /* and end the buffer */
  1403. X    z += count;                /* add # of chars inserted */
  1404. X    dot += count;
  1405. X    ctrl_s = -count;        /* save string length */
  1406. X    }
  1407. X
  1408. X/* subroutine to delete n characters starting at dot    */
  1409. X/* argument is number of characters                        */
  1410. X
  1411. Xdelete1(nchars)
  1412. X    int nchars;
  1413. X    {
  1414. X    if (!nchars) return;        /* 0 chars is a nop */
  1415. X    if (nchars < 0)        /* delete negative number of characters? */
  1416. X        {
  1417. X        nchars = -nchars;            /* make ll positive */
  1418. X        if (nchars > dot) ERROR(E_POP);        /* don't delete beyond beg of buffer */
  1419. X        dot -= nchars;                /* put pointer before deleted text */
  1420. X        }
  1421. X    else if (dot + nchars > z) ERROR(E_POP);    /* don't delete beyond end of buffer */
  1422. X
  1423. X    set_pointer(dot, &aa);            /* pointer to beginning of area to delete */
  1424. X    set_pointer(dot+nchars, &bb);    /* and to end */
  1425. X    if (dot < buff_mod) buff_mod = dot;        /* update earliest char loc touched */
  1426. X    movenchars(&bb, &aa, z-(dot+nchars));    /* move text unless delete ends at z */
  1427. X    free_blist(aa.p->f);            /* return any cells after end */
  1428. X    aa.p->f = NULL;                    /* end the buffer */
  1429. X    z -= nchars;                    /* adjust z */
  1430. X    }
  1431. X
  1432. X/* routine to process "O" command */
  1433. X
  1434. Xstruct qh obuff;        /* tag string buffer */
  1435. X
  1436. Xdo_o()
  1437. X    {
  1438. X    int i, j;            /* i used as start of tag, j as end */
  1439. X    int p, level;        /* p is pointer to tag string, level is iteration lvl */
  1440. X    int epfound;        /* flag for "second ! found"        */
  1441. X
  1442. X    if (!build_string(&obuff)) return;        /* no tag spec'd: continue */
  1443. X    if (obuff.z > CELLSIZE) ERROR(E_STL);    /* string too long */
  1444. X    esp->op = OP_START;                        /* consume any argument */
  1445. X    if (esp->flag1)                            /* is there one? */
  1446. X        {
  1447. X        esp->flag1 = 0;                        /* consume it */
  1448. X        if (esp->val1 < 0) return;            /* computed goto out of range - */
  1449. X        for (i = 0; (i < obuff.z) && (esp->val1 > 0); i++)        /* scan to find right tag */
  1450. X            if (obuff.f->ch[i] == ',') esp->val1--;                /* count commas */
  1451. X        if (esp->val1 > 0) return;            /* computed goto out of range + */
  1452. X
  1453. X/* now i is either at 0 or after the nth comma */
  1454. X
  1455. X        for (j = i; j < obuff.z; j++)    /* find end of tag */
  1456. X            if (obuff.f->ch[j] == ',') break;        /* stop at next comma */
  1457. X        if (j == i) return;                /* two adjacent commas: zero length tag */
  1458. X        }
  1459. X
  1460. X    else
  1461. X        {
  1462. X        i = 0;                /* not a computed goto: use whole tag buffer */
  1463. X        j = obuff.z;
  1464. X        }
  1465. X
  1466. X/* start from beginning of iteration or macro, and look for tag */
  1467. X
  1468. X    if (cptr.flag & F_ITER)            /* if in iteration */
  1469. X        {
  1470. X        cptr.p = cptr.il->p;        /* restore */
  1471. X        cptr.c = cptr.il->c;
  1472. X        cptr.dot = cptr.il->dot;
  1473. X        }
  1474. X    else for (cptr.dot = cptr.c = 0; cptr.p->b->b != NULL; cptr.p = cptr.p->b);    /* find macro start */
  1475. X
  1476. X/* search for tag */
  1477. X
  1478. X    for (level = 0; ;)            /* look through rest of command string */
  1479. X        {
  1480. X        switch (skipto(1))        /* look for interesting things, including ! */
  1481. X            {
  1482. X            case '<':            /* start of iteration */
  1483. X                ++level;
  1484. X                break;
  1485. X
  1486. X            case '>':            /* end of iteration */
  1487. X                if ((level == 0) && (cptr.flag & F_ITER)) pop_iteration(1);
  1488. X                else --level;
  1489. X                break;
  1490. X
  1491. X            case '!':                /* start of tag */
  1492. X                for (epfound = 0; ; epfound = 0)        /* keep looking for tag */
  1493. X                    {
  1494. X                    for (p = i; p < j; p++)
  1495. X                        {
  1496. X                        if (getcmdc(0) == '!') epfound = 1;        /* mark "trailing ! found */
  1497. X                        if (mapch_l[cmdc] != mapch_l[obuff.f->ch[p]]) break;    /* compare */
  1498. X                        }
  1499. X                    if (p >= j)            /* if all comparison chars matched */
  1500. X                        {
  1501. X                        if (getcmdc(0) == '!') return;    /* and tag ends with !, found it */
  1502. X                        }
  1503. X                    else if (!epfound) while (getcmdc(0) != '!');        /* else look for next ! and continue */
  1504. X                    }
  1505. X                break;
  1506. X            }            /* end of switch */
  1507. X        }            /* end of scan loop */
  1508. X    }            /* end of subroutine */
  1509. X
  1510. X/* routine to skip to next ", ', |, <, or >            */
  1511. X/* skips over these chars embedded in text strings    */
  1512. X/* stops in ! if argument is nonzero                */
  1513. X/* returns character found, and leaves it in skipc    */
  1514. X
  1515. Xchar skipto(arg)
  1516. X    int arg;
  1517. X    {
  1518. X    int atsw;                /* "at" prefix */
  1519. X    char ta, term;            /* temp attributes, terminator */
  1520. X
  1521. X    for (atsw = 0; ;)        /* forever        */
  1522. X        {
  1523. X        while (!(ta = spec_chars[skipc = getcmdc(0)] & (A_X | A_S | A_T | A_Q)));    /* read until something interesting found */
  1524. X
  1525. X    again:
  1526. X        if (ta & A_Q) getcmdc(0);        /* if command takes a Q spec, skip the spec */
  1527. X        if (ta & A_X)                    /* sought char found: quit */
  1528. X            {
  1529. X            if (skipc == '"') getcmdc(0);    /* quote must skip next char */
  1530. X            return(skipc);
  1531. X            }
  1532. X        if (ta & A_S)                                /* other special char */
  1533. X            {
  1534. X            switch (skipc)
  1535. X                {
  1536. X                case '^':                            /* treat next char as CTL */
  1537. X                    if (ta = spec_chars[skipc = getcmdc(0) & 0x1f]) goto again;
  1538. X                    break;
  1539. X
  1540. X                case '@':                            /* use alternative text terminator */
  1541. X                    atsw = 1;
  1542. X                    break;
  1543. X
  1544. X                case CTL (^):                        /* ^^ is value of next char: skip that char */
  1545. X                    getcmdc(0);
  1546. X                    break;
  1547. X
  1548. X                case CTL (A):                        /* type text */
  1549. X                    term = (atsw) ? getcmdc(0) : CTL (A);
  1550. X                    atsw = 0;
  1551. X                    while (getcmdc(0) != term);        /* skip text */
  1552. X                    break;
  1553. X
  1554. X                case '!':                            /* tag */
  1555. X                    if (arg) return(skipc);
  1556. X                    while (getcmdc(0) != '!');        /* skip until next ! */
  1557. X                    break;
  1558. X
  1559. X                case 'e':                            /* first char of two-letter E or F command */
  1560. X                case 'f':
  1561. X                    if (spec_chars[getcmdc(0)] & ((skipc == 'e') ? A_E : A_F))         /* if one with a text arg */
  1562. X                        {
  1563. X                        term = (atsw) ? getcmdc(0) : ESC;
  1564. X                        atsw = 0;
  1565. X                        while (getcmdc(0) != term);        /* read past terminator */
  1566. X                        }
  1567. X                    break;
  1568. X                }                /* end "switch" */
  1569. X            }                /* end "if (ta & A_S)" */
  1570. X
  1571. X        else if (ta & A_T)                        /* command with a text argument */
  1572. X            {
  1573. X            term = (atsw) ? getcmdc(0) : ESC;
  1574. X            atsw = 0;
  1575. X            while (getcmdc(0) != term);            /* skip text */
  1576. X            }
  1577. X        }                /* end "forever" */
  1578. X    }                /* end "skipto()" */
  1579. X
  1580. X/* find number of characters to next matching (, [, or {  (like '%' in vi) */
  1581. X
  1582. Xdo_ctlp()
  1583. X    {
  1584. X    int i, l;
  1585. X    char c, c1;
  1586. X
  1587. X    set_pointer(dot, &aa);            /* point to text buffer */
  1588. X    switch(c1 = aa.p->ch[aa.c])
  1589. X        {
  1590. X        case '(':
  1591. X            c = ')';            /* match char is ) */
  1592. X            i = 1;                /* direction is positive */
  1593. X            break;
  1594. X
  1595. X        case ')':
  1596. X            c = '(';            /* match char is ( */
  1597. X            i = -1;                /* direction is negative */
  1598. X            break;
  1599. X
  1600. X        case '[':
  1601. X            c = ']';
  1602. X            i = 1;
  1603. X            break;
  1604. X
  1605. X        case ']':
  1606. X            c = '[';
  1607. X            i = -1;
  1608. X            break;
  1609. X
  1610. X        case '{':
  1611. X            c = '}';
  1612. X            i = 1;
  1613. X            break;
  1614. X
  1615. X        case '}':
  1616. X            c = '{';
  1617. X            i = -1;
  1618. X            break;
  1619. X
  1620. X        case '<':
  1621. X            c = '>';
  1622. X            i = 1;
  1623. X            break;
  1624. X
  1625. X        case '>':
  1626. X            c = '<';
  1627. X            i = -1;
  1628. X            break;
  1629. X
  1630. X        case '"':
  1631. X            c = '\'';
  1632. X            i = 1;
  1633. X            break;
  1634. X
  1635. X        case '\'':
  1636. X            c = '"';
  1637. X            i = -1;
  1638. X            break;
  1639. X
  1640. X        default:
  1641. X            esp->val1 = i = 0;        /* not on a matchable char, return 0 */
  1642. X        }
  1643. X
  1644. X    l = 1;            /* start with one unmatched char */
  1645. X    if (i > 0)        /* if searching forward */
  1646. X        {
  1647. X        for (i = dot, fwdc(&aa); (i < z) && (l); fwdc(&aa) )
  1648. X            {
  1649. X            ++i;
  1650. X            if (aa.p->ch[aa.c] == c) --l;
  1651. X            else if (aa.p->ch[aa.c] == c1) ++l;
  1652. X            }
  1653. X        esp->val1 = (i < z) ? i - dot : 0;
  1654. X        }
  1655. X    else if (i < 0)
  1656. X        {
  1657. X        for (i = dot, backc(&aa); (i >= 0) && (l); backc(&aa) )
  1658. X            {
  1659. X            --i;
  1660. X            if (aa.p->ch[aa.c] == c) --l;
  1661. X            else if (aa.p->ch[aa.c] == c1) ++l;
  1662. X            }
  1663. X        esp->val1 = (i >= 0) ? i - dot : 0;
  1664. X        }
  1665. X    esp->flag1 = 1;
  1666. X    }
  1667. X
  1668. END_OF_te_subs.c
  1669. if test 13995 -ne `wc -c <te_subs.c`; then
  1670.     echo shar: \"te_subs.c\" unpacked with wrong size!?
  1671. fi
  1672. # end of overwriting check
  1673. fi
  1674. echo shar: End of archive 2 \(of 4\).
  1675. cp /dev/null ark2isdone
  1676. DONE=true
  1677. for I in 1 2 3 4 ; do
  1678.     if test ! -f ark${I}isdone ; then
  1679.     echo shar: You still need to run archive ${I}.
  1680.     DONE=false
  1681.     fi
  1682. done
  1683. if test "$DONE" = "true" ; then
  1684.     echo You have unpacked all 4 archives.
  1685.     echo "See the *.doc files"
  1686.     rm -f ark[1-9]isdone
  1687. fi
  1688. ##  End of shell archive.
  1689. exit 0
  1690.